package com.blog.cloud.auth.service.impl;

import cn.hutool.core.util.RandomUtil;
import com.blog.cloud.api.vo.LoginRequestDto;
import com.blog.cloud.api.vo.LoginResponseVo;
import com.blog.cloud.auth.service.AuthService;
import com.blog.cloud.cache.utils.RedisUtil;
import jakarta.mail.internet.MimeMessage;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

@Slf4j
@Service
@RequiredArgsConstructor
public class AuthServiceImpl implements AuthService {

    private final JavaMailSender javaMailSender;
    private final RedisUtil redisUtil;

    @Override
    public LoginResponseVo login(LoginRequestDto authLoginRequestDto) {
        switch (authLoginRequestDto.getAuthType()) {
            case USERNAME_PASSWORD -> authenticateByUsernamePassword(authLoginRequestDto.getIdentifier(), authLoginRequestDto.getCredential());
            case PHONE_CODE -> authenticateByPhoneCode(authLoginRequestDto.getIdentifier(), authLoginRequestDto.getCredential());
            case EMAIL_CODE -> authenticateByEmailCode(authLoginRequestDto.getIdentifier(), authLoginRequestDto.getCredential());
            default -> throw new BadCredentialsException("Unsupported authentication type");
        };

        return null;
    }

    @Override
    public String refreshAccessToken(String refreshToken) {
        // TODO 检查 refreshToken 是否存在 Redis


        // TODO 验证 refreshToken 是否过期

        // TODO 创建新的 accessToken
        // 可选：更新 refreshToken 的有效期或发放新的 refreshToken
        return "";
    }

    @Override
    public String register(LoginRequestDto authLoginRequestDto) {

        return "";
    }

    @Override
    public String sendSmsCode(LoginRequestDto loginRequestDto) {
        // TODO 发送短信验证码
        return "";
    }

    @Override
    public String sendEmailCode(LoginRequestDto loginRequestDto) {
        // 创建一个邮件信息发送对象，用于封装邮件信息
        MimeMessage mimeMessage = javaMailSender.createMimeMessage();
        try {
            // 创建 MimeMessageHelper
            MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
            // 生成随机验证码
            String verificationCode = RandomUtil.randomNumbers(6);
            // TODO 存储验证码到 Redis，并设置过期时间

            // 收件人
            helper.setTo(loginRequestDto.getIdentifier());
            // 邮件主题，相当于邮件的目的精炼介绍
            helper.setSubject("您的验证码");
            // 邮件内容
            helper.setText("你好,\n\n您的验证码是: " + verificationCode + "\n\nBest regards,\nThe Team");

            javaMailSender.send(mimeMessage);
        } catch (Exception e) {
            log.error("发送邮件出错，错误信息为:[{}]",e.getMessage(),e);
        }
    }



    private LoginResponseVo authenticateByUsernamePassword(String username, String password) {
        // 实现用户名密码认证逻辑

        // TODO 根据用户名查询数据库是否存在


        // ...
        return null;
    }

    private LoginResponseVo authenticateByPhoneCode(String phoneNumber, String code) {
        // 实现手机号验证码认证逻辑
        // 验证短信验证码是否正确
        if (smsService.verifyCode(phoneNumber, code)) {
            // 查找并返回用户详情
            return userRepository.findByPhoneNumber(phoneNumber).orElseThrow(() -> new UsernameNotFoundException("User not found"));
        } else {
            throw new BadCredentialsException("Invalid verification code");
        }
    }

    private LoginResponseVo authenticateByEmailCode(String email, String code) {
        // 实现邮箱验证码认证逻辑
        // TODO 从 Redis 获取指定邮箱的验证码，并验证邮箱验证码是否正确
        String redisCode = (String) redisUtil.get(email);
        if (emailService.verifyCode(email, code)) {
            // 查找并返回用户详情
            return userRepository.findByEmail(email).orElseThrow(() -> new UsernameNotFoundException("User not found"));
        } else {
            throw new BadCredentialsException("Invalid verification code");
        }
    }
}
